/**
* @author Ashish Gupta
* CVSSP, University of Surrey
* Copyright (c) 2010 Ashish Gupta
* All rights reserved.
*/
/**
 * 
 */
package data;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import net.sf.javaml.core.Dataset;
import net.sf.javaml.core.DefaultDataset;
import net.sf.javaml.core.DenseInstance;
import net.sf.javaml.core.Instance;

/**
 * @author Ashish
 *
 */
public class VisualCodebook {
	
	private ArrayList<ArrayList<Double>> visualCodebook = new ArrayList<ArrayList<Double>>();

	/**
	 * 
	 */
	public VisualCodebook() {
		super();
	}

	/**
	 * @param visualCodebook
	 */
	public VisualCodebook(ImageSet imageSet) {
		for(int i=0;i<imageSet.getImages().size();i++){
			ArrayList<Double> cbvector = new ArrayList<Double>();
			cbvector.add(imageSet.getImages().get(i).getClassLabel());
			cbvector.addAll(imageSet.getImages().get(i).getHistogram());
			this.visualCodebook.add(cbvector );
		}
	}
	
	/**
	 * @param visualCodebook the visualCodebook to set
	 */
	public void setVisualCodebook(ArrayList<ArrayList<Double>> visualCodebook) {
		this.visualCodebook = visualCodebook;
	}

	/**
	 * @return the visualCodebook
	 */
	public ArrayList<ArrayList<Double>> getVisualCodebook() {
		return visualCodebook;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("");
		for(int i=0;i<this.visualCodebook.size();i++){
			sb.append(this.visualCodebook.get(i).get(0));
			sb.append(" ");
			for(int j=1;j<this.visualCodebook.get(i).size();j++){
				sb.append(j);
				sb.append(":");
				sb.append(this.visualCodebook.get(i).get(j));
				sb.append(" ");
			}
			sb.append("\n");
		}
		return sb.toString();
	}

	/**
	 * @param filename
	 * @throws IOException
	 */
	public void toFile(String filename) throws IOException{
		File file = new File(filename);
		FileWriter fw = new FileWriter(file);
		fw.write(this.toString());
		fw.close();
	}
	
	/**
	 * @return Dataset
	 */
	public Dataset toDataset(){
		Dataset data = new DefaultDataset();
		Iterator<ArrayList<Double>> itr = this.visualCodebook.iterator();
		while(itr.hasNext()){
			ArrayList<Double> featureVector = itr.next();
//			String classLabel = null;
//			if(featureVector.get(0) == 1){
//				classLabel = "positive";
//			}
//			else{
//				classLabel = "negative";
//			}
			Double classLabel = featureVector.get(0);
			double[] featureVectorValues = new double[featureVector.size()-1];
			for(int i=0;i<featureVector.size()-1;i++){
				featureVectorValues[i] = featureVector.get(i+1);
			}
			Instance instance = new DenseInstance(featureVectorValues,classLabel);
			data.add(instance);
		}
		return data;
	}
	
	public void toARFFfile(String fileURL) throws IOException{
		File file = new File(fileURL);
		FileWriter fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("@RELATION visualcategory" + "\n");
		for(int i=0;i<this.visualCodebook.get(0).size();i++){
			bw.write("@ATTRIBUTE " + i + " NUMERIC" + "\n");
		}
		bw.write("@ATTRIBUTE" + " class " + "{positive,negative}" + "\n");
		bw.write("@DATA" + "\n");
		for(int i=0;i<this.visualCodebook.size();i++){
			for(int j=1;j<this.visualCodebook.get(i).size();j++){//note j starts from 1 instead of 0
				bw.write(this.visualCodebook.get(i).get(j) + ",");
			}
//			bw.write(this.visualCodebook.get(i).get(0) + "\n");
			if(this.visualCodebook.get(i).get(0) == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}
	
	public void toCSVfile(String fileURL) throws Exception{
		File file = new File(fileURL);
		FileWriter fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		for(int i=0;i<this.visualCodebook.size();i++){
			for(int j=1;j<this.visualCodebook.get(i).size();j++){//note j starts from 1 instead of 0
				bw.write(this.visualCodebook.get(i).get(j) + ",");
			}
//			bw.write(this.visualCodebook.get(i).get(0) + "\n");
			if(this.visualCodebook.get(i).get(0) == 1){
				bw.write("positive" + "\n");
			}
			else{
				bw.write("negative" + "\n");
			}
		}
		bw.close();
		fw.close();
	}
	
	public void readCodebook(String fileName) throws IOException{
		File file = new File(fileName);
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String cbvector;
		while((cbvector = br.readLine()) != null){
			String[] inLine = cbvector.split(" ");
			ArrayList<Double> vector = new ArrayList<Double>();
			vector.add(Double.parseDouble(inLine[0]));
			for(int i = 1;i<inLine.length;i++){
				String[] word = inLine[i].split(":");
				vector.add(Double.parseDouble(word[1]));
			}
			this.visualCodebook.add(vector);
		}
	}
	
}
